use crate::core::error::AppError;
use zbus::{Connection, dbus_proxy};
use std::time::Duration;

/// PolicyKit 动作ID (必须与 .policy 文件对应)
pub mod actions {
    /// 基础安装权限
    pub const INSTALL: &str = "org.deepin.linglong.install";
    /// 企业签名包安装
    pub const INSTALL_ENTERPRISE: &str = "org.deepin.linglong.install-enterprise";
    /// 增量更新权限
    pub const APPLY_DELTA: &str = "org.deepin.linglong.apply-delta";
    /// 跨架构安装权限
    pub const CROSS_ARCH: &str = "org.deepin.linglong.install-cross-arch";
    /// 沙盒配置权限
    pub const SANDBOX_CONFIG: &str = "org.deepin.linglong.sandbox-config";
}

/// 权限检查结果结构体
#[derive(Debug)]
pub struct PolicyResult {
    pub is_authorized: bool,
    pub is_challenge: bool,
    pub details: Vec<(String, String)>,
}

/// 策略管理器
pub struct PolicyManager {
    conn: Connection,
}

#[dbus_proxy(
    interface = "org.freedesktop.PolicyKit1.Authority",
    default_service = "org.freedesktop.PolicyKit1",
    default_path = "/org/freedesktop/PolicyKit1/Authority"
)]
trait PolkitAuthority {
    async fn check_authorization(
        &self,
        subject: (String, std::collections::HashMap<&str, zbus::zvariant::Value<'_>>),
        action_id: &str,
        details: std::collections::HashMap<&str, &str>,
        flags: u32,
    ) -> zbus::Result<(bool, bool, Vec<(String, String)>)>;
}

impl PolicyManager {
    /// 创建新策略管理器
    pub async fn new() -> Result<Self, AppError> {
        let conn = Connection::system().await?;
        Ok(Self { conn })
    }

    /// 检查指定操作的授权状态
    pub async fn check_authorization(
        &self,
        action_id: &str,
        interaction: AuthInteraction,
    ) -> Result<PolicyResult, AppError> {
        let proxy = PolkitAuthorityProxy::new(&self.conn).await?;
        
        // 构造认证主题（当前进程）
        let mut subject = std::collections::HashMap::new();
        subject.insert("pid", zbus::zvariant::Value::U32(std::process::id()));
        
        // 设置认证标志位
        let flags = match interaction {
            AuthInteraction::AllowUserInteraction => 1u32,  // POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION
            AuthInteraction::None => 0u32,
        };

        let (is_authorized, is_challenge, details) = proxy
            .check_authorization(
                ("unix-process".to_string(), subject),
                action_id,
                std::collections::HashMap::new(),
                flags,
            )
            .await?;

        Ok(PolicyResult {
            is_authorized,
            is_challenge,
            details,
        })
    }

    /// 执行特权操作（自动处理授权流程）
    pub async fn perform_privileged<F, T, E>(
        &self,
        action_id: &str,
        operation: F,
    ) -> Result<T, AppError>
    where
        F: FnOnce() -> Result<T, E>,
        E: Into<AppError>,
    {
        let result = self.check_authorization(action_id, AuthInteraction::AllowUserInteraction).await?;
        
        match result {
            PolicyResult { is_authorized: true, .. } => operation().map_err(Into::into),
            PolicyResult { is_challenge: true, .. } => {
                // 启动图形化认证对话框
                self.launch_auth_agent(action_id).await?;
                operation().map_err(Into::into)
            }
            _ => Err(AppError::PermissionDenied(
                format!("操作 {} 未授权", action_id)
            )),
        }
    }

    /// 启动图形化认证代理
    async fn launch_auth_agent(&self, action_id: &str) -> Result<(), AppError> {
        let desktop_entry = "com.deepin.linglong.policykit";
        
        let status = tokio::process::Command::new("pkexec")
            .arg("--disable-internal-agent")
            .arg("--")
            .arg("linglong-auth-helper")
            .arg(action_id)
            .status()
            .await?;

        if !status.success() {
            Err(AppError::AuthenticationFailed(
                "用户取消授权或认证失败".into()
            ))
        } else {
            Ok(())
        }
    }
}

/// 用户交互模式
pub enum AuthInteraction {
    /// 允许显示认证对话框
    AllowUserInteraction,
    /// 静默检查
    None,
}

/// 特权操作执行器（宏实现）
#[macro_export]
macro_rules! require_privilege {
    ($manager:expr, $action:expr, $code:block) => {
        $manager.perform_privileged($action, || $code).await
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_basic_auth_check() {
        let mgr = PolicyManager::new().await.unwrap();
        let result = mgr.check_authorization(actions::INSTALL, AuthInteraction::None)
            .await
            .unwrap();
        
        // 在测试环境中应该返回未授权状态
        assert!(!result.is_authorized);
        assert!(result.is_challenge);
    }
}